package org.gd.hellojaxb.utils;

import javax.xml.bind.*;
import java.io.*;

/**
 * @author Gorhover
 * @version 3.2
 */
public final class Marshall {

    private static volatile Marshall INSTANCE = null;
    private Marshaller.Listener listener = null;

    private Marshall() {
    }

    public static Marshall getInstance() {
        if(INSTANCE == null) {
            synchronized (Marshall.class) {
                if(INSTANCE == null) {
                    INSTANCE = new Marshall();
                }
            }
        }
        return INSTANCE;
    }

    @SuppressWarnings("unused")
    public Marshall setListener(Marshaller.Listener listener) {
        this.listener = listener;
        return this;
    }

    public String marshal(Object instance, MarshallProperties...props)
            throws JAXBException {
        return marshal(instance.getClass(), instance, props);
    }

    public String marshal(Class<?> clazz, Object instance, MarshallProperties...props)
            throws JAXBException {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        marshal(clazz, instance, pw, props);
        return sw.toString();
    }

    public void marshal(Class<?> clazz, Object instance, Writer writer, MarshallProperties...props)
            throws JAXBException {
        Marshaller marshaller = JAXBContext
                .newInstance(clazz)
                .createMarshaller();
        if(listener != null) {
            marshaller.setListener(listener);
        }
        if(props != null) {
            for (MarshallProperties prop: props) {
                marshaller.setProperty(prop.getKey(), prop.getValue());
            }
        }
        marshaller.marshal(instance, writer);
        this.listener = null;
    }
}
